﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Aioms.Common;
using Aioms.Controllers;
using Aioms.Models;
using EasyQuartz;
using Furion;
using Furion.DatabaseAccessor;
using Quartz;
using SqlSugar;
using SqlSugar.Extensions;

namespace Aioms.Cron
{
    //[TriggerCron("0/1 * * * * ? *")]
    //[TriggerCron("0 0 1 * * ? *")]
    [DisallowConcurrentExecution]
    public class PlanJob : IJob
    {
        private readonly ISqlSugarClient db; // 核心对象：拥有完整的SqlSugar全部功能
        public PlanJob()
        {
            this.db = new SqlSugarClient(new ConnectionConfig
            {
                ConnectionString = App.Configuration["ConnectionStrings:Default"],
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute//从特性读取主键自增信息
            });
            //处理日志事务
            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                Console.WriteLine(sql);
                Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));
                Console.WriteLine();
            };
        }
        public async Task Execute(IJobExecutionContext context)
        {
            Console.WriteLine($"{DateTime.Now} 计划任务开始执行");
            // 如果当前任务计划执行过，将不再执行
            Croninfo croninfo = await db.Queryable<Croninfo>().Where(c => c.Leixing == "计划" && c.Created.Date == DateTime.Now.Date).SingleAsync();
            if (croninfo == null)
            {
                String format_current_date = DateTime.Now.ToString("yyyy-MM-dd");

                int day_of_week = Convert.ToInt32(DateTime.Now.DayOfWeek); // 本周几
                int day_of_month = Convert.ToInt32(DateTime.Now.Day);

                #region 临时计划
                // 临时计划
                List<TaskPlan> temp_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.Period == "临时").Where(tp => tp.Status == "ok").ToListAsync();
                if (temp_taskPlanList?.Count > 0)
                {
                    foreach (var ttp in temp_taskPlanList)
                    {
                        String js_temp_date = ttp.BeginDate.ToString("yyyy-MM-dd");
                        if (js_temp_date.Equals(format_current_date))
                        {
                            // 发送到工单数据库
                            await db.Insertable<WorkOrder>(new WorkOrder { Eid = ttp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss"), Source = "计划", RefId = ttp.Id, Name = ttp.Name, Type = ttp.Type.Replace("计划", "工单"), Extra = ttp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ttp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ttp.EndTime), ManHour = ttp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = ttp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", Progress = "" }).ExecuteCommandAsync();
                        }
                    }
                }
                Console.WriteLine("临时计划执行结束！！！");
                #endregion

                #region 周计划
                // 周计划
                List<TaskPlan> week_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.Period == "周").Where($"FIND_IN_SET({day_of_week}, period_day)").Where(tp => tp.Status == "ok").ToListAsync();
                if (week_taskPlanList?.Count > 0)
                {
                    foreach (var wtp in week_taskPlanList)
                    {
                        // 发送到工单数据库
                        await db.Insertable<WorkOrder>(new WorkOrder { Eid = wtp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss"), Source = "计划", RefId = wtp.Id, Name = wtp.Name, Type = wtp.Type.Replace("计划", "工单"), Extra = wtp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + wtp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + wtp.EndTime), ManHour = wtp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = wtp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", Progress = "" }).ExecuteCommandAsync();
                    }
                }
                Console.WriteLine("周计划执行结束！！！");
                #endregion

                #region 月计划
                // 月计划
                List<TaskPlan> month_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.Period == "月").Where($"FIND_IN_SET({day_of_month}, period_day)").Where(tp => tp.Status == "ok").ToListAsync();
                if (month_taskPlanList.Count > 0)
                {
                    foreach (var mtp in month_taskPlanList)
                    {
                        // 发送到工单数据库
                        await db.Insertable<WorkOrder>(new WorkOrder { Eid = mtp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss"), Source = "计划", RefId = mtp.Id, Name = mtp.Name, Type = mtp.Type.Replace("计划", "工单"), Extra = mtp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + mtp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + mtp.EndTime), ManHour = mtp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = mtp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", Progress = "" }).ExecuteCommandAsync();
                    }
                }
                Console.WriteLine("月计划执行结束！！！");
                #endregion

                #region 年计划
                // 年计划
                List<TaskPlan> year_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.Period == "年").Where(tp => tp.Status == "ok").ToListAsync();
                if (year_taskPlanList?.Count > 0)
                {
                    foreach (var ytp in year_taskPlanList)
                    {
                        // 计算出来年计划多少天后的日期
                        DateTime js_year_date = ytp.BeginDate.AddDays(Convert.ToInt32(ytp.PeriodDay));
                        String format_js_date = js_year_date.ToString("yyyy-MM-dd");

                        // 跟当前时间作比较，看是否是当天
                        if (format_current_date.Equals(format_js_date))
                        {
                            // 发送到工单数据库
                            await db.Insertable<WorkOrder>(new WorkOrder { Eid = ytp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss"), Source = "计划", RefId = ytp.Id, Name = ytp.Name, Type = ytp.Type.Replace("计划", "工单"), Extra = ytp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ytp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ytp.EndTime), ManHour = ytp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = ytp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", Progress = "" }).ExecuteCommandAsync();
                        }
                    }
                }
                Console.WriteLine("年计划执行结束！！！");
                #endregion

                await db.Insertable<Croninfo>(new Croninfo { Leixing = "计划" }).ExecuteCommandAsync();
            }
        }

        public async Task<XunJianPlan> GetXunJianData(long id)
        {
            XunJianPlan xjp = new();

            // 第一步：查找巡检路线
            InspectionLine il = await db.Queryable<InspectionLine>().InSingleAsync(id);
            if (il != null)
            {
                xjp.Id = il.Id;
                xjp.Eid = il.Eid;
                xjp.Name = il.Name;
                // 第二步：查找巡检点
                List<InspectionPoint> ips = await db.Queryable<InspectionPoint>().Where(ip => ip.Id == il.Id).ToListAsync();
                foreach (var ip in ips)
                {
                    XunJianDian xjd = new();
                    xjd.Id = ip.Id;
                    xjd.Eid = ip.Eid;
                    xjd.Name = ip.Name;
                    xjd.Position = ip.Position;
                    xjd.Range = ip.Range;
                    // 第三步：查找巡检点巡检项
                    List<InspectionOption> ios = await db.Queryable<InspectionOption>().Where(io => io.Id == ip.Id).ToListAsync();
                    foreach (var io in ios)
                    {
                        XunJianDianXunJianXiang xjdxjx = new();
                        xjdxjx.Id = io.Id;
                        xjdxjx.Eid = io.Eid;
                        xjdxjx.Procedure = io.Procedure;
                        xjdxjx.Record = io.Record;
                        xjdxjx.Option = io.Option;
                        xjdxjx.ImageUrl = io.Image;
                        xjdxjx.VideoUrl = io.Video;

                        xjd.XunJianXiangs.Add(xjdxjx);
                    }

                    // 第四步：查找设备
                    List<Device> devices = await db.Queryable<Device>().Where($"json_contains({ip.Dvids}, json_array(id))").ToListAsync();
                    foreach (var device in devices)
                    {
                        XunJianDevice xjdv = new();
                        xjdv.Id = device.Id;
                        xjdv.Eid = device.Eid;
                        xjdv.Name = device.Name;
                        xjdv.AeName = device.Aename;
                        xjdv.Position = device.Position;

                        // 第五步：根据设备类型查找巡检项
                        List<InspectionStandard> istds = await db.Queryable<InspectionStandard>().Where(istd => istd.Dvtid == device.Dvtid).ToListAsync();
                        foreach (var istd in istds)
                        {
                            DeviceXunJianStandard dxjs = new();
                            dxjs.Id = istd.Id;
                            dxjs.Eid = istd.Eid;
                            dxjs.Procedure = istd.Procedure;
                            dxjs.Record = istd.Record;
                            dxjs.Option = istd.Option;
                            dxjs.ImageUrl = istd.ImgUrl;
                            dxjs.VideoUrl = istd.VideoUrl;

                            xjdv.DeviceXunJianStandards.Add(dxjs);
                        }

                        xjd.XunJianDevices.Add(xjdv);
                    }

                    xjp.XunJianDians.Add(xjd);
                }
            }
            return xjp;
        }

        public async Task<DianJianPlan> GetDianJianData(string dvids)
        {
            DianJianPlan djp = new();

            // 第一步：查找设备
            List<Device> devices = await db.Queryable<Device>().Where($"FIND_IN_SET(id, '{dvids}')").ToListAsync();
            foreach (var device in devices)
            {
                DianJianDevice djdv = new();
                djdv.Id = device.Id;
                djdv.Eid = device.Eid;
                djdv.Name = device.Name;
                djdv.AeName = device.Aename;
                djdv.Position = device.Position;

                // 第二步：根据设备类型查找巡检项
                List<PointInspectionStandard> pistds = await db.Queryable<PointInspectionStandard>().Where(pistd => pistd.Dvtid == device.Dvtid).ToListAsync();
                foreach (var pistd in pistds)
                {
                    DeviceDianJianStandard ddjs = new();
                    ddjs.Id = pistd.Id;
                    ddjs.Eid = pistd.Eid;
                    ddjs.Standard = pistd.Standard;
                    ddjs.Record = pistd.Record;
                    ddjs.Option = pistd.Option;
                    ddjs.ImageUrl = pistd.ImgUrl;
                    ddjs.VideoUrl = pistd.VideoUrl;

                    djdv.DeviceDianJianStandards.Add(ddjs);
                }

                djp.DianJianDevices.Add(djdv);
            }
            return djp;
        }

        public async Task<BaoYangPlan> GetBaoYangData(string dvids)
        {
            BaoYangPlan byp = new();

            // 第一步：查找设备
            List<Device> devices = await db.Queryable<Device>().Where($"FIND_IN_SET(id, '{dvids}')").ToListAsync();
            foreach (var device in devices)
            {
                BaoYangDevice bydv = new();
                bydv.Id = device.Id;
                bydv.Eid = device.Eid;
                bydv.Name = device.Name;
                bydv.AeName = device.Aename;
                bydv.Position = device.Position;

                // 第二步：根据设备类型查找巡检项
                List<MaintenanceStandard> pistds = await db.Queryable<MaintenanceStandard>().Where(pistd => pistd.Dvtid == device.Dvtid).ToListAsync();
                foreach (var pistd in pistds)
                {
                    DeviceBaoYangStandard dbys = new();
                    dbys.Id = pistd.Id;
                    dbys.Eid = pistd.Eid;
                    dbys.Standard = pistd.Standard;
                    dbys.Position = pistd.Position;
                    dbys.ImageUrl = pistd.ImgUrl;
                    dbys.VideoUrl = pistd.VideoUrl;

                    bydv.DeviceBaoYangStandards.Add(dbys);
                }

                byp.BaoYangDevices.Add(bydv);
            }
            return byp;
        }
    }
}
